// 九、类型推论和兼容性

// 1.类型推论

// 1.1基础

// let name = 'lp'
// name = 123

// 1.2多类型联合

let arr6 = [1, 'a']
// arr6 = [2,'b',false]

// 1.3上下文类型

window.onmousedown = (mouseEvent) => {
  console.log(mouseEvent.a);
}

// 2.类型兼容性

// 2.1基础

interface InfoInterface {
  name: string,
  info: {
    age: number
  }
}
let infos: InfoInterface
const infos1 = {
  name: 'lp', info: {
    age: 19
  }
}
const infos2 = { age: 18 }
const infos3 = { name: 'lp', age: 18 }
infos = infos1
// infos = infos2
// infos = infos3

// 2.2 函数兼容性

// 2.2.1参数个数

// let x = (a: number) => 0
// let y = (a: number, c: string) => 0

// y = x
// x=y

// 2.2.2参数类型

// let x = (a: number) => 0
// let y = (b: string) => 0

// x = y

// 2.2.2.1可选参数和剩余参数

const getSum = (arr: number[], callback: (...args: number[]) => number): number => {
  return callback(...arr)
}
const res = getSum([1, 2, 3], (...args: number[]): number => args.reduce((a, b) => a + b, 0))
console.log(res);
// const res1 = getSum([1,2,3],(arg1:number,arg2:number,arg3:number):number=>arg1+arg2+arg3)
// console.log(res1);
// 2.2.2.2参数双向协变

let funcA = (arg: number | string): void => { }
let funcB = (arg: number): void => { }
// funcA = funcB
// funcB = funcA

// 2.2.3返回值类型

let x = (): string | number => 0
let y = (): string => 'a'
let z = (): boolean => false
// x = y
// y = x
// y = z
// 2.2.4 函数重载
// 当两个参数是数值，返回值是数值
function merge(arg1: number, arg2: number): number
// 当两个参数是字符串，返回值是字符串
function merge(arg1: string, arg2: string): string

function merge(arg1: any, arg2: any) {
  return arg1 + arg2
}

// 3.枚举兼容性
// 数值类型枚举只和数值类型兼容
enum StatusEnum {
  On, Off
}
enum AnimalEnum {
  Dog
  , Cat
}

// let s = StatusEnum.On
// s = AnimalEnum.Dog

// 4.类兼容性

class AnimalClass {
  public static age: number
  constructor(public name: string) { }
}
class PeopleClass {
  public static age: string
  constructor(public name: string) { }
}
class FoodIsClass {
  constructor(public name: number) { }
}

let animal: AnimalClass
let people: PeopleClass
let food: FoodIsClass

// 只会比较实例上的成员
// animal = people
// animal = food

// 类的私有属性和受保护属性的兼容性

class ParentClass{
  private age:number
  constructor(){}
}
class ChildrenClass extends ParentClass{
  constructor(){
    super()
  }
}
class OtherClass{
  private age:number
  constructor(){}
}
// const children:ParentClass = new ChildrenClass()
// const other:ParentClass = new OtherClass()


// 5.泛型兼容性

interface Data<T>{
  data:T
}
let data1:Data<number>
let data2:Data<string>
// data1 = data2



